package dev;

/*
 * 设备模块
 * 时间:2014-10-02
 * @version:0.1
 */
public class Index {

	private static int devA;// 资源A
	private static int devB;// 资源B
	private static int devC;// 资源C

	private static java.util.Map<String, Integer> procAndResource;// 资源分配表
	private static java.util.Set<Integer> waitQueue;// 等待队列

	static {
		devA = 1;
		devB = devC = 2;
		procAndResource = new java.util.TreeMap<String, Integer>();
		waitQueue = new java.util.TreeSet<Integer>();
	}

	private boolean check(int devANumber, int devBNumber, int devCNumber) {// 判断是否应该分配，静态资源分配法

		if (devANumber <= devA && devBNumber <= devB && devCNumber <= devC) {
			return true;
		} else {
			return false;
		}

	}

	private void loginResource(int procId, String type, int all, int need) {// 记录资源分配
		for (int i = 0; i <= need; i++) {
			procAndResource.put(type + (all - i), procId);
		}
	}

	/*
	 * 申请设备
	 * 
	 * @param procId 进程id
	 * 
	 * @param devANumber 资源A个数
	 * 
	 * @param devBNumber 资源B个数
	 * 
	 * @param devCNumber 资源C个数
	 */
	public boolean apply(int procId, int devANumber, int devBNumber,
			int devCNumber) {
		if (check(devANumber, devBNumber, devCNumber)) {
			// 尝试删除阻塞队列的该进程，没有则忽略
			waitQueue.remove(procId);
			// 把数据记录到资源分配表
			loginResource(procId, "A", devA, devANumber);
			loginResource(procId, "B", devB, devBNumber);
			loginResource(procId, "C", devC, devCNumber);

			devA = devA - devANumber;
			devB = devB - devBNumber;
			devC = devC - devCNumber;

		} else {// 把进程加入阻塞列表
			waitQueue.add(procId);
			return false;
		}

		controller.Ram.getObject().getPcbs()[procId - 1].setHaveDev(true);

		return true;
	}

	/*
	 * 释放设备
	 * 
	 * @param procId 进程id
	 */
	public boolean free(int procId) {
		java.util.Set<String> set = procAndResource.keySet();
		for (String tempKey : set) {// 获取map里面所有key

			Integer tempProcId = procAndResource.get(tempKey);
			if (tempProcId != null && tempProcId.intValue() == procId) {// 释放资源
				if (tempKey.startsWith("A")) {
					devA++;
				} else if (tempKey.startsWith("B")) {
					devB++;
				} else {
					devC++;
				}
			}
			procAndResource.put(tempKey, null);
		}
		controller.Ram.getObject().getPcbs()[procId - 1].setHaveDev(false);
		return true;

	}

	/*
	 * 获取资源分配表
	 * 
	 * @return map 资源分配表
	 */
	public java.util.Map<String, Integer> getProcAndResource() {
		return procAndResource;
	}

	public java.util.Set<Integer> getWaitQueue(){
		return waitQueue;
	}
	
}
